package com.jingsong.gp_print_util

import android.bluetooth.BluetoothAdapter
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbManager.ACTION_USB_DEVICE_ATTACHED
import android.hardware.usb.UsbManager.ACTION_USB_DEVICE_DETACHED
import android.os.Bundle
import android.util.Log
import com.example.untitled.model.DishInfoModel
import com.example.untitled.printactivity.*
import com.example.untitled.util.Utils
import com.google.gson.Gson
import com.jingsong.gp_print_util.printactivity.BluetoothDeviceList
import com.jingsong.gp_print_util.printactivity.Constant.ACTION_USB_PERMISSION
import com.jingsong.gp_print_util.printactivity.Constant.BLUETOOTH_REQUEST_CODE
import com.jingsong.gp_print_util.printactivity.DeviceConnFactoryManager.*
import com.jingsong.gp_print_util.printactivity.PrinterCommand
import com.jingsong.gp_print_util.printactivity.ThreadPool
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.view.FlutterMain

class MainActivity : FlutterActivity(), MethodChannel.MethodCallHandler,
    EventChannel.StreamHandler {
    private var threadPool: ThreadPool? = null
    private var channel: MethodChannel? = null
    private var eventChannel: EventChannel? = null
    private var eventSink: EventChannel.EventSink? = null

    private var msgResult: MethodChannel.Result? = null

    private var connectionChannel: EventChannel? = null
    private var msgConnectionResult: EventChannel.EventSink? = null

    private var mBluetoothAdapter: BluetoothAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        FlutterMain.startInitialization(this)
        super.onCreate(savedInstanceState)


        // Get the local Bluetooth adapter
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
        initBroadcast()
    }

    private fun initBroadcast() {
        val filter = IntentFilter(ACTION_USB_PERMISSION)//USB访问权限广播
        filter.addAction(ACTION_USB_DEVICE_DETACHED)//USB线拔出
        filter.addAction(ACTION_QUERY_PRINTER_STATE)//查询打印机缓冲区状态广播，用于一票一控
        filter.addAction(ACTION_CONN_STATE)//与打印机连接状态
        filter.addAction(ACTION_USB_DEVICE_ATTACHED)//USB线插入
        registerReceiver(receiver, filter)
    }

    private val receiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            Log.e("tag", "action =  ${intent?.action}")
            when (intent?.action) {
                ACTION_CONN_STATE -> {
                    val state = intent.getIntExtra(STATE, -1)
                    val deviceId = intent.getIntExtra(DEVICE_ID, -1)
                    val map = HashMap<String, Any>()
                    map["code"] = state
                    when (state) {
                        CONN_STATE_DISCONNECT -> Log.e("tag", "CONN_STATE_DISCONNECT")
                        CONN_STATE_CONNECTING -> Log.e("tag", "CONN_STATE_CONNECTING")
                        CONN_STATE_FAILED -> Log.e("tag", "CONN_STATE_FAILED")
                        CONN_STATE_CONNECTED -> {
                            val macAdd = getDeviceConnFactoryManagers()[0].macAddress
                            map["address"] = macAdd
                        }
                    }
                    msgConnectionResult?.success(map)
                }
            }
        }
    }

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        channel =
            MethodChannel(flutterEngine.dartExecutor.binaryMessenger, Utils.MSG_RECEIPT_PRINT)
        channel?.setMethodCallHandler(this)

        eventChannel =
            EventChannel(flutterEngine.dartExecutor.binaryMessenger, Utils.MSG_BTDEVICE_LIST)
        eventChannel?.setStreamHandler(this)

        connectionChannel =
            EventChannel(flutterEngine.dartExecutor.binaryMessenger, Utils.MSG_BTCONNECT)
        connectionChannel?.setStreamHandler(this)
    }

    /**
     * 打印票据例子
     *
     * @param view
     */
    fun btnReceiptPrint(model: DishInfoModel) {
        if (getDeviceConnFactoryManagers()[0] == null || !getDeviceConnFactoryManagers()[0].connState) {
            Log.e("tag", "蓝牙设备未连接")
            msgResult?.success(-999)
            return
        }
        threadPool = ThreadPool.getInstantiation()
        threadPool?.addSerialTask {
            if (getDeviceConnFactoryManagers()[0].currentPrinterCommand == PrinterCommand.ESC) {
                getDeviceConnFactoryManagers()[0].sendDataImmediately(
                    PrintContent.getReceipt(model)
                )
                msgResult?.success(1)
            } else {
                Log.e("tag", "打印命令发送失败")
                msgResult?.success(-1)
            }
        }
    }

    private fun connectBt(macAddress: String?) {
        closeport()
        Log.e("tag", "mac = $macAddress")
        //初始化话DeviceConnFactoryManager
        Build()
            .setId(0) //设置连接方式
            .setConnMethod(CONN_METHOD.BLUETOOTH) //设置连接的蓝牙mac地址
            .setMacAddress(macAddress)
            .build()
        //打开端口
        threadPool = ThreadPool.getInstantiation()
        threadPool?.addSerialTask { getDeviceConnFactoryManagers()[0].openPort() }
    }

    private fun closeport() {
        if (getDeviceConnFactoryManagers()[0] != null && getDeviceConnFactoryManagers()[0].mPort != null) {
            getDeviceConnFactoryManagers()[0].cancelThread()
            getDeviceConnFactoryManagers()[0].mPort.closePort()
            getDeviceConnFactoryManagers()[0].mPort = null
        }
    }

    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
        msgResult = result
        Log.e("tag", "call == ${call.method}")
        when (call.method) {
            "receiptPrint" -> {
                val dataStr = call.argument("data") as String?
                Log.e("tag", "data = $dataStr")
                val model = Gson().fromJson(dataStr, DishInfoModel::class.java)
                btnReceiptPrint(model)
            }
//            连接蓝牙
            "connectBT" -> {
                val macAddress = call.argument("mac") as String?
                connectBt(macAddress)
            }
//            断开蓝牙连接
            "disconnectBT" -> closeport()
            //设备状态
            "deviceStatus" -> {

            }
            "checkBTState" -> {
                val flag = mBluetoothAdapter?.isEnabled
                Log.e("tag", "蓝牙是否打开  = $flag")
                result.success(flag)
            }
            "searchBTDevices" -> startActivityForResult(
                Intent(
                    this,
                    BluetoothDeviceList::class.java
                ), BLUETOOTH_REQUEST_CODE
            )
        }
    }

    override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
        eventSink = events
        msgConnectionResult = events
//        通知结束时调用event#endOfStream，此时onCancel会被调用
//        必要时，可通过evnetSink#error发送错误通知，flutter的StreamSubscription#onError会收到通知
    }

    override fun onCancel(arguments: Any?) {
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == RESULT_OK) {
            when (requestCode) {
                BLUETOOTH_REQUEST_CODE -> {
                    val macAddress = data.getStringExtra(BluetoothDeviceList.EXTRA_DEVICE_ADDRESS)
                    connectBt(macAddress)
                }
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(receiver)
        closeAllPort()
        if (threadPool != null) {
            threadPool?.stopThreadPool()
        }
    }
}